// 引入核心模块
const express = require('express');
const cors = require('cors');
const multer = require('multer');
const fs = require('fs');
const path = require('path');
const jwt = require('jsonwebtoken');

// 权限配置项
const AUTH_CONFIG = {
  secret: 'YOUR_SECRET_KEY',
  expiresIn: '2h',
  apiWhiteList: ['/api/upload', '/api/login']
};

// 初始化Express应用
const app = express();
const PORT = process.env.PORT || 3300;
app.use(express.json({ limit: '10mb' }));

// 新增date-fns模块引入
const { format } = require('date-fns');

// 配置中间件
app.use(cors({
  origin: '*',
  methods: ['GET', 'POST', 'PUT', 'DELETE'],
  allowedHeaders: ['Content-Type', 'Authorization']
})); // 跨域支持

// JWT鉴权中间件
app.use((req, res, next) => {
  if (AUTH_CONFIG.apiWhiteList.includes(req.path)) return next();
  const token = req.headers.authorization ? req.headers.authorization.split(' ')[1] : null;
  if (!token) return res.status(401).json({ code: 401, error: '未提供访问令牌' });
  jwt.verify(token, AUTH_CONFIG.secret, (err, decoded) => {
    if (err) return res.status(403).json({ code: 403, error: '无效的访问令牌' });
    req.user = decoded;
    next();
  });
});
app.use(express.json()); // JSON请求体解析

// 请求日志中间件
app.use((req, res, next) => {
  const start = Date.now();
  res.on('finish', () => {
    const duration = Date.now() - start;
    console.log(`${req.method} ${req.originalUrl} - ${res.statusCode} (${duration}ms)`);
  });
  next();
});

// 创建上传目录
const uploadDir = path.join(__dirname, 'file');
!fs.existsSync(uploadDir) && fs.mkdirSync(uploadDir);

// 配置multer存储
const storage = multer.diskStorage({
  destination: (req, file, cb) => {
    const uploadDate = format(new Date(), 'yyyyMMdd');
    const dateDir = path.join(uploadDir, 'image', uploadDate);
    !fs.existsSync(dateDir) && fs.mkdirSync(dateDir, { recursive: true });
    cb(null, dateDir);
  },
  filename: (req, file, cb) => cb(null, Date.now() + '-' + file.originalname)
});

const upload = multer({
  storage: storage,
  limits: { fileSize: 100 * 1024 * 1024 } // 10MB限制
});

// 文件内容写入接口（追加模式,先判断文件是否存在,如果存在则将新的内容追加到文件末尾）
app.post('/api/writeFile', (req, res) => {
  try {
    const { filename, content } = req.body;

    // 文件名安全验证
    if (!/^[\p{Script=Han}a-zA-Z0-9_\-.]{1,50}$/u.test(filename)) {
      return res.status(200).json({ code: 500, message: '文件名包含非法字符' });
    }

    // 构建安全文件路径
    // 前置条件验证
    if (!filename || !content) {
      return res.status(200).json({ code: 500, message: '缺少必要参数' });
    }

    const filePath = path.join(__dirname, 'file', 'user_files', filename);
    // 创建目录（如不存在）
    const dirPath = path.dirname(filePath);
    console.log('dirPath', dirPath)
    if (!fs.existsSync(dirPath)) {
      // 添加目录创建日志
      console.log('创建目录:', dirPath);
      fs.mkdirSync(dirPath, { recursive: true });
    }

    // 写入文件内容（追加模式）
    fs.writeFileSync(filePath, content + '\n', { flag: 'a' });

    res.json({
      code: 200,
      data: {
        path: `/file/user_files/${filename}`,
        size: fs.statSync(filePath).size
      }
    });
  } catch (err) {
    console.error('文件写入失败:', err);
    res.status(500).json({ code: 500, message: '文件操作失败' });
  }
});

// 文件创建接口（自动创建新文件,生成文件名并将文件内容写入）
app.post('/api/createFile', (req, res) => {
  try {
    const { fileType, content } = req.body;

    // 安全验证
    if (!/^[\p{Script=Han}a-zA-Z0-9_\-.]{1,50}$/u.test(fileType)) {
      return res.status(200).json({ code: 500, message: '非法文件类型格式' });
    }

    // 创建类型目录
    const typeDir = path.join(__dirname, 'file', fileType);
    if (!fs.existsSync(typeDir)) {
      fs.mkdirSync(typeDir, { recursive: true });
    }

    // 生成唯一文件名
    const filename = `${format(new Date(), 'yyyyMMdd')}-${Math.random().toString(36).slice(2, 7)}.txt`;
    const filePath = path.join(typeDir, filename);

    // 写入文件内容
    fs.writeFileSync(filePath, content, 'utf8');

    res.json({
      code: 200,
      data: {
        path: `/file/${fileType}/${filename}`,
        fullPath: filePath
      }
    });
  } catch (err) {
    console.error('文件创建失败:', err);
    res.status(500).json({ code: 500, message: '文件创建失败' });
  }
});

// 文件上传接口(返回文件信息及文件存储路径)
app.post('/api/upload', upload.single('file'), (req, res) => {
  const uploadDate = format(new Date(), 'yyyyMMdd');
  // 创建日期目录
  const dateDir = path.join(uploadDir, 'image', uploadDate);
  if (!fs.existsSync(dateDir)) {
    fs.mkdirSync(dateDir, { recursive: true });
  }
  if (!req.file) {
    return res.status(400).json({ error: '请选择要上传的文件' });
  }
  res.json({
    success: true,
    filename: req.file.filename,
    size: req.file.size,
    path: `/file/image/${uploadDate}/${req.file.filename}`
  });
});

// 用户登录接口
app.post('/api/login', (req, res) => {
  const { username, password } = req.body;

  // 模拟用户验证（实际应查询数据库）
  if (username !== 'admin' || password !== '123456') {
    return res.status(401).json({ code: 401, error: '无效的凭证' });
  }

  // 生成JWT
  const token = jwt.sign({
    userId: 1,
    username: 'admin'
  }, AUTH_CONFIG.secret, { expiresIn: '2h' });
  res.json({
    code: 200,
    data: {
      token: token,
    },
    msg: '登录成功'
  })
});

// 权限校验接口
app.post('/api/auth/check', (req, res) => {
  res.json({
    code: 200,
    data: {
      permissions: ['file:read', 'file:write'],
      roles: ['admin']
    }
  });
});
// 获取user_files目录文件列表接口
app.get('/api/listFiles', (req, res) => {
  res.setHeader('Cache-Control', 'no-store'); // 添加缓存控制
  res.setHeader('Expires', '0');
  try {
    const filesDir = path.join(__dirname, 'file', 'user_files');

    if (!fs.existsSync(filesDir)) {
      return res.json({ code: 200, data: [], message: '目录不存在' });
    }

    const files = fs.readdirSync(filesDir).map(file => file);
    res.json({
      code: 200,
      data: files,
      message: 'success'
    });
  } catch (err) {
    console.error('获取文件列表失败:', err);
    res.status(500).json({
      code: 500,
      message: '服务器内部错误'
    });
  }
});


// 文章存储目录
const articlesDir = path.join(__dirname, 'file', 'articles');
!fs.existsSync(articlesDir) && fs.mkdirSync(articlesDir, { recursive: true });

// 文章管理API
app.post('/api/articles', upload.single('coverImage'), (req, res) => {
  try {
    const { title, content, category } = req.body;
    const filename = `${Date.now()}-${title.replace(/[^a-zA-Z0-9]/g, '-')}.json`;
    const filePath = path.join(articlesDir, filename);
    const uploadDate = format(new Date(), 'yyyyMMdd');

    const articleData = {
      id: filename,
      title,
      content,
      category,
      coverImage: req.file ? `/file/image/${uploadDate}/${req.file.filename}` : null,
      createTime: new Date().toISOString(),
      views: 0
    };

    fs.writeFileSync(filePath, JSON.stringify(articleData));
    res.json({ code: 200, data: articleData });
  } catch (err) {
    console.error('文章创建失败:', err);
    res.status(500).json({ code: 500, message: '文章创建失败' });
  }
});

app.get('/api/articles', (req, res) => {
  try {
    const files = fs.readdirSync(articlesDir)
      .map(file => {
        const data = fs.readFileSync(path.join(articlesDir, file), 'utf8');
        return JSON.parse(data);
      });
    res.json({ code: 200, data: files });
  } catch (err) {
    console.error('获取文章列表失败:', err);
    res.status(500).json({ code: 500, message: '获取文章失败' });
  }
});

// 文件读取接口
app.get('/api/readFile', (req, res) => {
  try {
    const { filename } = req.query;

    // 文件名安全验证（与写入接口保持一致）
    if (!/^[\p{Script=Han}a-zA-Z0-9_\-.]{1,50}$/u.test(filename)) {
      return res.status(200).json({ code: 400, message: '非法文件名' });
    }

    const filePath = path.join(__dirname, 'file', 'user_files', filename);

    // 检查文件是否存在
    if (!fs.existsSync(filePath)) {
      return res.status(200).json({ code: 404, message: '文件不存在' });
    }

    // 读取文件内容（UTF-8编码）
    const content = fs.readFileSync(filePath, 'utf8');

    res.json({
      code: 200,
      data: {
        content: content,
        path: `/file/user_files/${filename}`,
        size: fs.statSync(filePath).size
      }
    });
  } catch (err) {
    console.error('文件读取失败:', err);
    res.status(500).json({ code: 500, message: '文件读取失败' });
  }
});

// 404处理中间件
app.use((req, res) => {
  res.status(404).json({ error: 'Endpoint not found' });
});

// 全局错误处理器
app.use((err, req, res, next) => {
  console.error(err.stack);
  res.status(500).json({ error: 'Internal server error' });
});

// 启动服务器
app.listen(PORT, () => {
  console.log(`Server running on port ${PORT}`);
});

